#pragma once

#include "Object.h"
#include <memory>
#include "Component.h"
#include <glm/gtc/quaternion.hpp>


class  GameObject : public Object
{

public:
    explicit GameObject(Context* context);
    ~GameObject() override;
       
    void SetPosition(const glm::vec3& position);
    const glm::vec3& GetPosition() const { return position_; }
    const glm::vec3& GetWorldPosition();

    const glm::vec3& GetScale() const { return scale_; }
    const glm::vec3& GetRotation() const { return rotation_; }
    void SetScale(const glm::vec3& scale);
    void SetScale(float scale);
    void SetRotation(const glm::vec3& angle);
    void SetRotation(const glm::quat& angle);

    virtual const glm::mat4x4& GetTransform() const;
    void MarkDirty();

    const std::vector<std::shared_ptr<GameObject>> GetChildren() const { return children_; }
    void AddChild(std::shared_ptr<GameObject> element);
    void RemoveChild(std::shared_ptr<GameObject>  element);

	GameObject* GetParent() { return parent_; }
    std::string GetName() { return name_; }
    void SetName(std::string name);
        
    const std::vector<std::shared_ptr<Component>>& GetComponents() { return components_; }
    void AddComponent(std::shared_ptr<Component> comp);
    void RemoveComponent(std::shared_ptr<Component> comp);

    const unsigned char& GetMask() { return cameraMask_ ;}

    GameObject* Clone();
protected:
    std::vector<std::shared_ptr<Component>> components_{};
    glm::vec3 position_{0.f}; 
    glm::vec3 scale_{1.0f};
    glm::vec3 rotation_{0.f};
	mutable glm::vec3 worldPosition_{ 0.f };
	mutable bool positionDirty_{true};
	GameObject* parent_{};
	std::vector<std::shared_ptr<GameObject>> children_{};
	mutable glm::mat4x4 transform_{};
	std::string name_{};
    unsigned char cameraMask_{ 0xff };
};

